<?php

class SearchController extends MainController implements ControllerInterface {
	
	private static $listType = '__search_list_type__';	
	
	public $tableConfig = array(
		'products_list' => array(
			'o' => array(
				'name' => 'product_description.name',
				'popularity' => 'product.popularity',
				'rate' => 'product.rate',
				'brand' => 'manufacturer.name',
				'_' => 'popularity',
			),
			'v' => 'a',
			't' => 10
		)
	);
	
	protected $tables = array(
		'products_list' => array(
			'o' => array(
				'name' => 'product_description.name',
				'popularity' => 'product.popularity',
				'rate' => 'product.rate',
				'brand' => 'manufacturer.name',
				'_' => 'popularity',
			),
			'v' => 'a',
			't' => 10
		)		
	); 	
	
	public function IndexAction($param) {
		try {
			
			/** to musi byc tu - w przeciwnym razie nadpisze zmienne szablonu **/
			$this->RunShared('CategoriesAndBrands', $param); 
			
			/** zmienne **/
			$searchString = ''; // szukany string
			if(isset($param['query']))
			{
				$searchString = str_replace('%20', ' ', Request::CleanXss($param['query']));
			}else{
				$this->AddDescription("");
				$this->AddTitle("search");	
				$this->addRedirectInfo($this->t('Invalid search string.'),'error',Router::GenerateUrl('default'),0);
				return;

			}
			$propIds = array();
			$propSql = '';
			$popularity = array();
			$rate = array();
			$rating = array();
			$filterProperties = array();
			$filterCompanies = array();
			$selectedCompanies = array();
			$extra = array();
			$premium = array();
			/** ustalenie widoku strony **/
			if(isset($_GET['switch']))
			{
				$viewClass = SessionProxy::GetValue(self::$listType, 'list');
				if($viewClass == 'list')
				{
					SessionProxy::SetValue(self::$listType, 'box');
				} else {
					SessionProxy::SetValue(self::$listType, 'list');
				}
			}			
			$viewClass = SessionProxy::GetValue(self::$listType, 'list');
			$this->smarty->assign('listType', $viewClass);
			/** koniec - ustalenei widoku strony **/
			// parametry
			$this->smarty->assign('categoryKey', 'search');
			$this->smarty->assign('subCategoryKey', $param['query']);			
			$this->smarty->assign('params', $param);
			
			/** odczyt danych z sesji **/
			$data = SessionProxy::GetValue('__product_list_selected_popularity__', array());
			SessionProxy::ClearValue('__product_list_selected_popularity__');
			if(isset($data['search']))
			{
				$popularity = $data['search'];
				SessionProxy::SetValue('__product_list_selected_popularity__', array('search' => $popularity));
			}

			$data = SessionProxy::GetValue('__product_list_selected_rate__', array());
			SessionProxy::ClearValue('__product_list_selected_rate__');
			if(isset($data['search']))
			{
				$rate = $data['search'];
				SessionProxy::SetValue('__product_list_selected_rate__', array('search' => $rate));
			}
			
			$data = SessionProxy::GetValue('__search_selected_companies__', array());
			SessionProxy::ClearValue('__search_selected_companies__');
			if(isset($data['search']))
			{
				$selectedCompanies = $data['search'];
				SessionProxy::SetValue('__search_selected_companies__', array('search' => $selectedCompanies));
			}		
			
			$data = SessionProxy::GetValue('__search_selected_extra__', array());
			SessionProxy::ClearValue('__search_selected_extra__');
			if(!empty($data['search']))
			{
				$extra = $data['search'];
				SessionProxy::SetValue('__search_selected_extra__', array('search' => $extra));
			}	
			$data = SessionProxy::GetValue('__search_selected_premium__', array());
			SessionProxy::ClearValue('__search_selected_premium__');
			if(isset($data['search']))
			{
				$premium = $data['search'];
				SessionProxy::SetValue('__search_selected_premium__', array('search' => $premium));
			}			
			
			
			/** obsluga POST  **/
			if(Request::IsPost())
			{
				
				$type = Request::Get('formType');
				switch($type)
				{
					case 'browseOptions':
						SessionProxy::ClearValue('__search_selected_companies__');
						$selectedCompanies = Request::Get('cmp');
						if(!empty($selectedCompanies))
						{
							SessionProxy::SetValue('__search_selected_companies__', array('search' => $selectedCompanies));
						} else {
							$selectedCompanies = array();
						}		
						
						SessionProxy::ClearValue('__search_selected_extra__');
						$extra = Request::Get('extra');
						if(!empty($extra))
						{
							$_extra = array();
								foreach($extra as $k => $v)
								{
									if($v == 0)
									{
										continue;
									}
									$_extra[$k] = $v;
								}
								$extra = $_extra;							
							SessionProxy::SetValue('__search_selected_extra__', array('search' => $extra));
						}
						
						break;
					
					case 'ratingBrowseOptions':
					{
						// rating browse options
						$popularity = Request::Get('popularity'); // array(min, max)
						SessionProxy::ClearValue('__product_list_selected_popularity__');
						SessionProxy::SetValue('__product_list_selected_popularity__', array('search' => $popularity));

						$rate = Request::Get('rate'); // array(min, max)
						SessionProxy::ClearValue('__product_list_selected_rate__');
						SessionProxy::SetValue('__product_list_selected_rate__', array('search' => $rate));
					}
					break;
				}
			}
			/** koniec post **/

			/** string wyszukiwania **/
			
			$searchStringArr = explode(' ', htmlspecialchars($searchString,ENT_QUOTES));
			foreach($searchStringArr as $k => $item)
			{
				$item = trim($item);
				
				if(mb_strlen($item) < 4)
				{
					unset($searchStringArr[$k]);
				} else {
					$searchStringArr[$k] = $item;
				}				
			}
			
			if(count($searchStringArr) > 6) 
			{
				$searchStringArr = array_slice($searchStringArr, 0, 6);
			}
			if(count($searchStringArr) > 1)
			{
				$_mc = count($searchStringArr) * (count($searchStringArr) - 1);
				$_sa = array();
				do {
					shuffle($searchStringArr);
					$_sa[] = implode('%', $searchStringArr);
					$_sa = array_unique($_sa);
				}while(count($_sa) != $_mc );
				$searchStringArr = array_unique($_sa);
			}
			
			$searchStringArr = array_unique($searchStringArr);
			/** koniec - string wyszukiwania **/

			
			if(empty($searchStringArr))
			{
				/* pusty string wyszukiwania */
				$this->AddDescription("");
				$this->AddTitle("search");	
				/*%C4%85 %C4%87 %C4%99 %C5%82 %C5%84 %C3%B3 %C5%9B %C5%BA %C5%BC */
				
				$this->AddTitle(str_replace(array('%2D', '%22', '%27', '%C4%85', '%C4%87', '%C4%99', '%C5%82', '%C5%84', '%C3%B3', '%C5%9B', '%C5%BA', '%C5%BC'), array('-', '"', '\'', 'ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż'), $searchString));
				$this->smarty->assign('emptyString', true);
				$this->smarty->assign('searchPhrase', str_replace(array('%2D', '%22', '%27', '%C4%85', '%C4%87', '%C4%99', '%C5%82', '%C5%84', '%C3%B3', '%C5%9B', '%C5%BA', '%C5%BC'), array('-', '"', '\'', 'ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż'), $searchString));
			} else {
				/* wyszukanie produktow */
				$this->smarty->assign('emptyString', false);
				$this->smarty->assign('searchPhrase', str_replace(array('%2D', '%22', '%27', '%C4%85', '%C4%87', '%C4%99', '%C5%82', '%C5%84', '%C3%B3', '%C5%9B', '%C5%BA', '%C5%BC'), array('-', '"', '\'', 'ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż'), $searchString));
				$this->AddDescription("");
				$this->AddTitle("search");
				$this->AddTitle(str_replace(array('%2D', '%22', '%27', '%C4%85', '%C4%87', '%C4%99', '%C5%82', '%C5%84', '%C3%B3', '%C5%9B', '%C5%BA', '%C5%BC'), array('-', '"', '\'', 'ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż'), $searchString));


				/** lista produuktow **/
				$dalData = ProductDAL::GetDalDataObj(array(
					'tableData' => $this->tableParams['products_list'],
					'condition' => array(
						'product.active' => array(1),
						'manufacturer.active' => array(1),
						'category.active' => array(1)
					),
					'join' => array(
						'ProductDescription' => ' LEFT JOIN product_description ON (product.id_product = product_description.id_product AND product_description.id_language = '.Registry::Get('APPLICATION_LANGUAGE_ID').')',
						'Manufacturer' => ' LEFT JOIN manufacturer ON (product.id_manufacturer = manufacturer.id_manufacturer)',
						'Category' => ' LEFT JOIN category ON (product.id_category = category.id_category) LEFT JOIN category c2 ON (c2.id_category = category.parent)',
						'CategoryDescription' => 'LEFT JOIN category_description ON (category_description.id_category = category.id_category OR category_description.id_category = c2.id_category)'
					)
				));		
				$dalData->addCondition('1 = 1', ' (CONCAT_WS(\' \', product_description.name, product_description.description, category_description.name, category_description.description, manufacturer.name) LIKE \'%' . implode('%\' OR CONCAT_WS(\' \', product_description.name, product_description.description, category_description.name, category_description.description, manufacturer.name) LIKE \'%', $searchStringArr) . '%\') ', 'AND', 'AND');
				$dalData->addJoin('PropertyValue', ' LEFT JOIN property_value ON(property_value.id_product = product.id_product)');
				$dalData->setGroupBy('product.id_product');	
				$dalData->addCondition('property_value.parent', 'NULL', 'IS NOT');		
				if(!empty($selectedCompanies))
				{
					$dalData->addCondition('product.id_manufacturer', implode(' OR product.id_manufacturer = ', $selectedCompanies), '=', 'AND');
				}
				if(!empty($extra))
				{
					foreach($extra as $k => $v)
					{
						$idType = null;
						switch($k)
						{
							case 'topRated':
								$idType = 2;
								break;

							case 'mostPopular':
								$idType = 3;
								break;

							case 'vip':
								$idType = 1;
								break;
						}
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM product_ranking WHERE type = ' . $idType . ')', 'IN');
					}					
				}
				
				if(isset($popularity['min']) && isset($popularity['max']))
				{
					$dalData->addCondition('product.popularity', $popularity['min'] . ' AND ' . $popularity['max'], 'BETWEEN');
				}

				if(isset($rate['min']) && isset($rate['max']))
				{
					$dalData->addCondition('product.rate', $rate['min'] . ' AND ' . $rate['max'], 'BETWEEN');
				}	

				if(!empty($rating))
				{
					foreach($rating as $k => $v)
					{
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM product_votes_ranking WHERE id_product_votes_type = ' . $k . ' AND value BETWEEN ' . $v['min'] . ' AND ' . $v['max'] .' )', ' IN');
					}
				}			
				if(!empty($premium))
				{
					$_conditions = '';
					foreach($premium as $k => $v)
					{
						if($k == 'hand') $_conditions .= 'AND (user_extended_profile.hand = ' . implode(' OR user_extended_profile.hand = ', $v) . ')';
						if($k == 'forehand') $_conditions .= 'AND (user_extended_profile.forehand = ' . implode(' OR user_extended_profile.forehand = ', $v) . ')';
						if($k == 'backhand') $_conditions .= 'AND (user_extended_profile.backhand = ' . implode(' OR user_extended_profile.backhand = ', $v) . ')';
						if($k == 'player_style') $_conditions .= 'AND (user_extended_profile.player_style = ' . implode(' OR user_extended_profile.player_style = ', $v) . ')';
						if($k == 'prefered_court_surface') $_conditions .= 'AND (user_extended_profile.prefered_court_surface = ' . implode(' OR user_extended_profile.prefered_court_surface = ', $v) . ')';
						if($k == 'ntrp') $_conditions .= ' AND (user_extended_profile.ntrp BETWEEN ' . $v['min'] . ' AND ' . $v['max'] . ')';
					}
					if(!empty($_conditions))
					{
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM user_equipment WHERE id_user IN (SELECT user_extended_profile.id_user FROM user_extended_profile  WHERE 1 = 1 ' . $_conditions . ' ))', 'IN');
					}
				}				
				
				$dalData2 = clone $dalData; 
				$dalData2->setAsCount('count(distinct(product.id_product))');
				$dalData2->setLimit("");
				$this->smarty->assign('c', 	ProductDAL::GetResult($dalData2)); // liczba produktow				
				$productsList = ProductDAL::GetResult($dalData);
				
				
				// rankingi
			$activeProductsIds = array();
			
			foreach($productsList as $product) {
				$activeProductsIds[] = $product->getId();
			}
			
			if(!empty($activeProductsIds))
			{
				$data = array();
				
				$dalObjr = ProductRankingDAL::GetDalDataObj();
				$dalObjr->addCondition('product_ranking.id_product', '(' . implode(', ', $activeProductsIds) .')', 'IN');
				$dalObjr->addJoin('ProductRankingType', ' LEFT JOIN product_ranking_type ON (product_ranking.type=product_ranking_type.id_product_ranking_type AND product_ranking_type.active = 1) ');
				$productRanking = ProductRankingDAL::GetResult($dalObjr);
				
				foreach($productRanking as $item)
				{
					if(!isset($data[$item->getIdProduct()]))$data[$item->getIdProduct()] = array('ranking' => array(), 'vote' => array());
					$data[$item->getIdProduct()]['ranking'][] = $item;
				}
				
				$dalObj = ProductVotesRankingDAL::GetDalDataObj();
				$dalObj->addJoin('ProductVotesType', ' JOIN product_votes_type on ( product_votes_type.id_product_votes_type = product_votes_ranking.id_product_votes_type ) ');
				$dalObj->addCondition('id_product', '(' . implode(', ', $activeProductsIds) .')', 'IN');

				$productVotes = ProductVotesRankingDAL::GetResult($dalObj);
				foreach($productVotes as $item)
				{
					if(!isset($data[$item->getIdProduct()]))$data[$item->getIdProduct()] = array('ranking' => array(), 'vote' => array());
					$data[$item->getIdProduct()]['vote'][] = $item;
				}				
				
				foreach($productsList as $k => $v)
				{
					if(isset($data[$v->getId()]))
					{
						if(isset($data[$v->getId()]['ranking']))
						{
							$productsList[$k]->setProductRanking($data[$v->getId()]['ranking']);
						}
						if(isset($data[$v->getId()]['vote']))
						{
							$productsList[$k]->setProductVotes($data[$v->getId()]['vote']);
						}						
					}
				}
			}				
				
				
				
				$this->smarty->assign('productsList', $productsList); // lista produktow ze stronicowaniem

				
				// firmy
				$dalData = ManufacturerDAL::GetDalDataObj(array(
					'condition' => array(
						'product.active' => array(1),
						'manufacturer.active' => array(1),
						'category.active' => array(1)
					),
					'join' => array(
						'Product' => 'LEFT JOIN product ON (product.id_manufacturer = manufacturer.id_manufacturer)',
						'ProductDescription' => ' LEFT JOIN product_description ON (product.id_product = product_description.id_product AND product_description.id_language = '.Registry::Get('APPLICATION_LANGUAGE_ID').')',
						'Category' => ' LEFT JOIN category ON (product.id_category = category.id_category) LEFT JOIN category c2 ON (c2.id_category = category.parent)',
						'CategoryDescription' => 'LEFT JOIN category_description ON (category_description.id_category = category.id_category OR category_description.id_category = c2.id_category)',
						'PropertyValue' => 'LEFT JOIN property_value ON(property_value.id_product = product.id_product)'
					)
				));
if(!empty($selectedCompanies))
				{
					$dalData->addCondition('product.id_manufacturer', implode(' OR product.id_manufacturer = ', $selectedCompanies), '=', 'AND');
				}
				if(!empty($extra))
				{
					foreach($extra as $k => $v)
					{
						$idType = null;
						switch($k)
						{
							case 'topRated':
								$idType = 2;
								break;

							case 'mostPopular':
								$idType = 3;
								break;

							case 'vip':
								$idType = 1;
								break;
						}
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM product_ranking WHERE type = ' . $idType . ')', 'IN');
					}					
				}
				
				if(isset($popularity['min']) && isset($popularity['max']))
				{
					$dalData->addCondition('product.popularity', $popularity['min'] . ' AND ' . $popularity['max'], 'BETWEEN');
				}

				if(isset($rate['min']) && isset($rate['max']))
				{
					$dalData->addCondition('product.rate', $rate['min'] . ' AND ' . $rate['max'], 'BETWEEN');
				}	

				if(!empty($rating))
				{
					foreach($rating as $k => $v)
					{
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM product_votes_ranking WHERE id_product_votes_type = ' . $k . ' AND value BETWEEN ' . $v['min'] . ' AND ' . $v['max'] .' )', ' IN');
					}
				}				
				if(!empty($premium))
				{
					$_conditions = '';
					foreach($premium as $k => $v)
					{
						if($k == 'hand') $_conditions .= 'AND (user_extended_profile.hand = ' . implode(' OR user_extended_profile.hand = ', $v) . ')';
						if($k == 'forehand') $_conditions .= 'AND (user_extended_profile.forehand = ' . implode(' OR user_extended_profile.forehand = ', $v) . ')';
						if($k == 'backhand') $_conditions .= 'AND (user_extended_profile.backhand = ' . implode(' OR user_extended_profile.backhand = ', $v) . ')';
						if($k == 'player_style') $_conditions .= 'AND (user_extended_profile.player_style = ' . implode(' OR user_extended_profile.player_style = ', $v) . ')';
						if($k == 'prefered_court_surface') $_conditions .= 'AND (user_extended_profile.prefered_court_surface = ' . implode(' OR user_extended_profile.prefered_court_surface = ', $v) . ')';
						if($k == 'ntrp') $_conditions .= ' AND (user_extended_profile.ntrp BETWEEN ' . $v['min'] . ' AND ' . $v['max'] . ')';
					}
					if(!empty($_conditions))
					{
						$dalData->addCondition('product.id_product', '(SELECT id_product FROM user_equipment WHERE id_user IN (SELECT user_extended_profile.id_user FROM user_extended_profile  WHERE 1 = 1 ' . $_conditions . ' ))', 'IN');
					}
				}				
				$dalData->addSelectFields('ProductsCount', 'count(distinct(product.id_product))');
				$dalData->addCondition('property_value.parent', 'NULL', 'IS NOT');
				$dalData->addCondition('1 = 1', ' (CONCAT_WS(\' \', product_description.name, product_description.description, category_description.name, category_description.description, manufacturer.name) LIKE \'%' . implode('%\' OR CONCAT_WS(\' \', product_description.name, product_description.description, category_description.name, category_description.description, manufacturer.name) LIKE \'%', $searchStringArr) . '%\') ', 'AND', 'AND');
				$dalData->setGroupBy('manufacturer.id_manufacturer');
				$filterCompanies = ProductDAL::GetResult($dalData);

			}			
			
			$this->smarty->assign('selectedPropertyValues', array());
			$this->smarty->assign('filterProperties', array());	
				
			
			$this->smarty->assign('filterCompanies', $filterCompanies);
			$this->smarty->assign('selectedCompanies', $selectedCompanies);
			

			
			
			/** kategorie - potrzebne do listy produktow **/
			$categories = CategoryDAL::GetResult(
					CategoryDAL::GetDalDataObj(
							array(
								'condition' => array(
									'active' => array('1')
								),
								'join' => array(
									'CategoryDescription' => ' LEFT JOIN category_description ON (category.id_category = category_description.id_category AND category_description.id_language = ' . Registry::Get('APPLICATION_LANGUAGE_ID') . ')'
								)
							)
						)
					);
			
			
			$_allCategories = array(
				'parents' => array(),
				'children' => array()
			);
			
			foreach($categories as $category)
			{
				if((int)$category->getParent() > 0)
				{
					$_allCategories['children'][$category->getId()] = $category;
				} else {
					$_allCategories['parents'][$category->getId()] = $category;
				}
			}	
			
			$this->smarty->assign('allCategories', $_allCategories);
			
			$this->smarty->assign('popularity', $popularity);
			$this->smarty->assign('rate', $rate);
			$this->smarty->assign('rating', $rating);
			$this->smarty->assign('extra', $extra);
			$this->smarty->assign('premium', $premium);
			
			
			
		} catch (Exception $e)
		{
			
			var_dump($e);
			
//			return $this->AddRedirect(Router::GenerateUrl('default'), 0);
		}
		
	}
	
	/**
	 * Czesc wspolna wszystkich podstron
	 *
	 */
	public function PreDispatch($param) {
		$this->Run($param);
		
	}

	public function PostDispatch($param) {
		
		// nagłówek strony
		$this->RunShared('Header', $param);

		
		// footer
		$this->RunShared('Footer', $param);
	}
	
}